package com.herui.iot.data;

import android.os.Environment;
import android.util.Log;

import com.herui.sdyu_lib.aliyun.oss.AliOssApp;
import com.herui.sdyu_lib.http.callback.Callback;
import com.herui.sdyu_lib.utils.FileUtils;
import com.herui.sdyu_lib.utils.ToastUtil;
import com.herui.sport_care.data.check.EvaluationStage;
import com.herui.sport_care.data.check.UpDataInfo;
import com.herui.sport_care.data.check.SecurityToken;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * Created by amanda.shan on 2022/12/7.
 */
public class SportFileManager {

    static String TAG = "SportFileManager";

    private String baseUrl = "https://ph-science-sports-train-assess.oss-cn-hangzhou.aliyuncs.com/";

    SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmssSSS");

    private String environment = "dev"; // 开发版本的是”dev“，预发版本的是”pre“,正式版本的是”prod“
    private SecurityToken securityToken;

    private OutputStream ecgOutputStream;
    private String ecgPath;

    /**
     * 开始心电存储
     * @param userId
     * @param evaluationSchemeId
     * @param stage
     * @throws FileNotFoundException
     */
    public void initEcgStore(Integer userId, Integer evaluationSchemeId,
                         EvaluationStage stage) throws IOException {
        String ecgPath = getEcgPath(userId, evaluationSchemeId, stage);
        if (ecgOutputStream != null && this.ecgPath !=null && !this.ecgPath.equals(ecgPath)){
            closeEcgStore();
        }
        if (ecgOutputStream == null){
            String dir = FileUtils.getExternalFilesDir(Environment.DIRECTORY_DCIM);
            File file = new File(dir,ecgPath);
            ecgOutputStream = new FileOutputStream(file);
            this.ecgPath = ecgPath;
        }
    }

    /**
     * 保存心电数据
     * @param userId                用户id
     * @param evaluationSchemeId    评估id
     * @param bytes
     *  @param stage    阶段
     */
    public synchronized void saveEcgData(Integer userId, Integer evaluationSchemeId, byte[] bytes,
                             EvaluationStage stage) throws IOException {

        if (ecgOutputStream != null){
            ecgOutputStream.write(bytes);
        }
    }

    public synchronized void closeEcgStore() throws IOException {
        if (ecgOutputStream != null){
            ecgOutputStream.close();
            ecgOutputStream = null;
            Log.i(TAG, "closeEcgStore: 结束心电数据存储:"+ecgPath);
            this.ecgPath = null;
        }
    }

    /**
     * 保存心率
     * @param userId
     * @param evaluationSchemeId
     * @param hearts
     * @throws IOException
     */
    public void saveHeart(Integer userId, Integer evaluationSchemeId, List<UpDataInfo> hearts) throws IOException {
        String dir = FileUtils.getExternalFilesDir(Environment.DIRECTORY_DCIM);
        File file = new File(dir, getHeartPath(userId, evaluationSchemeId));

        Writer writer = new FileWriter(file);
        writer.write("{\"data\":[");

        for (int i = 0; i < hearts.size(); i++) {
            UpDataInfo heartInfo =  hearts.get(i);
            if (i == 0){
                writer.write(String.format("[%d,%d]", heartInfo.getTime(), heartInfo.getValue()));
            }else{
                writer.write(String.format(",[%d,%d]", heartInfo.getTime(), heartInfo.getValue()));
            }
        }

        writer.write("]}");
        writer.close();
    }

    /**
     * 保存阻力
     * @param userId
     * @param evaluationSchemeId
     * @param values
     * @throws IOException
     */
    public void saveResistance(Integer userId, Integer evaluationSchemeId, List<UpDataInfo> values) throws IOException {
        String dir = FileUtils.getExternalFilesDir(Environment.DIRECTORY_DCIM);
        File file = new File(dir, getResistancePath(userId, evaluationSchemeId));

        Writer writer = new FileWriter(file);
        writer.write("{\"data\":[");

        for (int i = 0; i < values.size(); i++) {
            UpDataInfo heartInfo =  values.get(i);
            if (i == 0){
                writer.write(String.format("[%d,%d]", heartInfo.getTime(), heartInfo.getValue()));
            }else{
                writer.write(String.format(",[%d,%d]", heartInfo.getTime(), heartInfo.getValue()));
            }
        }

        writer.write("]}");
        writer.close();
    }

    /**
     * 上传心电
     * @param userId
     * @param evaluationSchemeId
     * @param stage
     */
    public String uploadEcg(Integer userId, Integer evaluationSchemeId, EvaluationStage stage){

        if (!checkOss()){
            return null;
        }

        String key = String.format("%s/ecg_data/assess/%s" +
                "/%s.txt", environment, stage.getOssKey(), format.format(new Date()));

        String dir = FileUtils.getExternalFilesDir(Environment.DIRECTORY_DCIM);
        File file = new File(dir, getEcgPath(userId, evaluationSchemeId, stage));

        boolean sucess = AliOssApp.getInstance().getAliOssUtils().put(key, file.getPath());
        Log.d(TAG, String.format("uploadEcg: sucess:%s key:%s, filepath:%s", sucess, key,
                file.getPath()));

        if (sucess){
            Log.i(TAG, "uploadEcg: "+key);
            return baseUrl+key;
        }

        return null;
    }

    /**
     * 上传心率数据文件
     * @param userId
     * @param evaluationSchemeId
     * @return
     */
    public String uploadHeart(Integer userId, Integer evaluationSchemeId){

        if (!checkOss()){
            return null;
        }

        String key = String.format("%s/trend/assess/heart_rate" +
                "/%s.txt", environment, format.format(new Date()));

        String dir = FileUtils.getExternalFilesDir(Environment.DIRECTORY_DCIM);
        File file = new File(dir, getHeartPath( userId, evaluationSchemeId));

        boolean sucess = AliOssApp.getInstance().getAliOssUtils().put(key, file.getPath());
        Log.d(TAG, String.format("uploadEcg: sucess:%s key:%s, filepath:%s", sucess, key,
                file.getPath()));

        if (sucess){
            Log.i(TAG, "uploadHeart: "+key);
            return baseUrl+key;
        }

        return null;
    }

    /**
     * 上传心率数据文件
     * @param userId
     * @param evaluationSchemeId
     * @return
     */
    public String uploadResistance(Integer userId, Integer evaluationSchemeId){

        if (!checkOss()){
            return null;
        }

        String key = String.format("%s/trend/assess/resistance" +
                "/%s.txt", environment, format.format(new Date()));

        String dir = FileUtils.getExternalFilesDir(Environment.DIRECTORY_DCIM);
        File file = new File(dir, getResistancePath( userId, evaluationSchemeId));

        boolean sucess = AliOssApp.getInstance().getAliOssUtils().put(key, file.getPath());
        Log.d(TAG, String.format("uploadEcg: sucess:%s key:%s, filepath:%s", sucess, key,
                file.getPath()));

        if (sucess){
            Log.i(TAG, "uploadResistance: "+key);
            return baseUrl+key;
        }

        return null;
    }

    /**
     * 获取心电存储路径
     * @param userId
     * @param evaluationSchemeId
     * @param stage
     * @return
     */
    private String getEcgPath(Integer userId, Integer evaluationSchemeId, EvaluationStage stage){
        return String.format("%s_ecg_%d_%d", stage.getOssKey(),userId, evaluationSchemeId);
    }

    /**
     * 获取心率路径
     * @param userId
     * @param evaluationSchemeId
     * @return
     */
    private String getHeartPath(Integer userId, Integer evaluationSchemeId){
        return String.format("heart_%d_%d", userId, evaluationSchemeId);
    }

    /**
     * 获取阻力路径
     * @param userId
     * @param evaluationSchemeId
     * @return
     */
    private String getResistancePath(Integer userId, Integer evaluationSchemeId){
        return String.format("resistance_%d_%d", userId, evaluationSchemeId);
    }

    private boolean checkOss(){
        if (securityToken == null || System.currentTimeMillis() - securityToken.getExpiration().getTime() > 0){
            securityToken = null;
            CustomFuture customFuture = new CustomFuture();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    RepositoryFactory.getInstance().getCheckSource().getOssToken(new Callback.CommonCallback<SecurityToken>() {
                        @Override
                        public void onSuccess(SecurityToken result) {
                            securityToken = result;
                            AliOssApp.getInstance().initOSSClient(result.getAccessKeyId(),
                                    result.getAccessKeySecret(), result.getSecurityToken());
                            customFuture.putResponse(true);
                        }

                        @Override
                        public void onError(Throwable e, String code, String message) {
                            ToastUtil.showMessage("获取OSS凭证失败");
                        }
                    });
                }
            }).start();

            try {
                customFuture.waitResponse(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
                return false;

            }
        }

        if (securityToken != null){
            return true;
        }
        return false;
    }
}
